package com.cx.common.utils;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.deser.std.StdDeserializer;
import org.codehaus.jackson.map.util.ArrayBuilders;

import java.io.IOException;

/**
 *
 * @Author:cxy
 * @Date:2019/10/24 15:11
 */
public class IntArrayDeserializer extends StdDeserializer<int[]> {

	public IntArrayDeserializer() {
		super(int[].class);
	}

	@Override
	public int[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {

		if (!jp.isExpectedStartArrayToken()) {
			return handleNonArray(jp, ctxt);
		}
		ArrayBuilders.IntBuilder builder = ctxt.getArrayBuilders().getIntBuilder();
		int[] chunk = builder.resetAndStart();
		int ix = 0;

		while (jp.nextToken() != JsonToken.END_ARRAY) {
			// whether we should allow truncating conversions?
			int value = _parseIntPrimitive(jp, ctxt);
			if (ix >= chunk.length) {
				chunk = builder.appendCompletedChunk(chunk, ix);
				ix = 0;
			}
			chunk[ix++] = value;
		}
		return builder.completeAndClearBuffer(chunk, ix);
	}

	private final int[] handleNonArray(JsonParser jp, DeserializationContext ctxt)
			throws IOException, JsonProcessingException {
		// [JACKSON-620] Empty String can become null...
		if ((jp.getCurrentToken() == JsonToken.VALUE_STRING)
				&& ctxt.isEnabled(DeserializationConfig.Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) {
			if (jp.getText().length() == 0) {
				return null;
			}
		}
		if (!ctxt.isEnabled(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)) {
			throw ctxt.mappingException(_valueClass);
		}

		JsonToken token = jp.getCurrentToken();
		if (token == JsonToken.VALUE_STRING) {
			String text = jp.getText().trim();
			String[] values = StringUtils.split(text, ',');
			if (ArrayUtils.isNotEmpty(values)) {
				int[] ret = new int[values.length];
				for (int i = 0; i < values.length; i++) {
					ret[i] = Integer.valueOf(values[i]);
				}
				return ret;
			}
		}

		return null;
	}

}
